module main_lazy(
	// System
	Clk,
	Rst_n,
	
	// Uart
	uart_tx,
	uart_rx,
	
	// Key
	Key0,
	Key2,
	key1,
	
	// LED
	Led0,
	Led1,
	Led2,
	Led3,

	// TFT
	TFT_RGB,
	TFT_HS,
	TFT_VS,
	TFT_CLK,
	TFT_DE,
	TFT_PWM
);
	// System
	input Clk;
	input Rst_n;
	
	// Uart
	output uart_tx;
	input uart_rx;
	
	// Key
	input Key0;
	input key1;
	input Key2;	
	
	// Led
	output Led0;
	output Led1;
	output Led2;
	output Led3;
	
	// tft output
	output TFT_HS;
	output TFT_VS;
	output TFT_CLK;
	output TFT_DE;
	output TFT_PWM;
	output [15:0]TFT_RGB;
	
	// 接收逻辑
	wire [8:0] rx_data;
	wire rx_done;
	reg [1:0] bps_setting;
	reg [1:0] check_setting;
	
	// 发送逻辑
	reg [8:0] tx_data;
	reg send_en;
	wire uart_state;
	
	// tft ram
	reg ram_wren;
	reg [11:0]ram_wraddress;
	reg ram_data;
	
	reg [11:0]receive_pos;
		
	// 按键状态
	wire Key0_p; 
	wire Key1_p; 
	wire Key2_p; 
	
	
	// 界面状态机
	reg system_state;
	reg [1:0]option;
	
	assign Led0 = system_state;
	assign Led1 = option[1];
	assign Led2 = option[0];
	
	// 更改配置项信号
	reg option_change;
	
	// 配置刷新
	reg flush_setting;
	reg [1:0]flush_setting_cnt;
	// 刷新发送字符设置
	reg flush_send_setting;
	reg flush_send_setting_signal;
	// 刷新波特率设置
	reg flush_bps_setting;
	reg [2:0] flush_bps_setting_cnt;
	reg flush_bps_setting_signal;
	reg [7:0] flush_bps_setting_data;
	reg [11:0] flush_bps_setting_address;
	// 刷新校验码设置
	reg flush_check_setting;
	reg [1:0]flush_check_setting_cnt;
	reg flush_check_setting_signal;
	reg [7:0] flush_check_setting_data;
	reg [11:0] flush_check_setting_address;
	
	wire tx_done;
	
	assign Led3 = option_change;
	
	button button_instance0(
		.clk(Clk) 			,
		.rst_n(Rst_n)			,
		.key(Key0)			,
		// key_r_flag  ,
		.key_p_flag(key0_p)		// Key0检测按下标志	
	);  
	
	button button_instance1(
		.clk(Clk) 			,
		.rst_n(Rst_n)			,
		.key(Key1)			,
		// key_r_flag  ,
		.key_p_flag(key1_p)		// Key1检测按下标志	
	);  
	
	button button_instance2(
		.clk(Clk) 			,
		.rst_n(Rst_n)			,
		.key(Key2)			,
		// key_r_flag  ,
		.key_p_flag(key2_p)		// Key2检测按下标志	
	);  
	
	// 接收逻辑 不动
	uart_byte_rx uart_byte_rx_instance0(
		.clk(Clk),			   // 时钟发生器：system 50MHz
		.rst_n(Rst_n), 			// 复位使能：reg
		.uart_rx(uart_rx),		   // 串口接受线: system
		.bps_setting(bps_setting), 	// 波特率：reg 
		.check_setting(check_setting), // 校验方式: reg
		.data(rx_data),			   // 数据: reg
		.rx_done(rx_done)   		// 一次接收数据完成标志
	);
	
	
	uart_byte_tx uart_byte_tx_instance0(
		.clk(Clk),			   // 时钟发生器：system 50MHz
		.data(tx_data),			   // 数据: reg
		.send_en(send_en),  	   // 使能: reg
		.bps_setting(bps_setting), 	// 波特率：reg 
		.check_setting(check_setting), // 校验方式: reg
		.rst_n(Rst_n), 			// 复位使能：reg
		
		.uart_tx(uart_tx),		   // 串口发送线: system
		.tx_done(tx_done),   		// 一次发送数据完成标志
		.uart_state(uart_state)		// 发送数据状态，发送过程中为1，其它时候为0
	);
	
	vision_ctrl vision_ctrl_instance0(
		.Clk(Clk),
		.Rst_n(Rst_n),
		.TFT_RGB(TFT_RGB),//TFT数据输出
		.TFT_HS(TFT_HS),	//TFT行同步信号
		.TFT_VS(TFT_VS),	//TFT场同步信号
		.TFT_CLK(TFT_CLK),
		.TFT_DE(TFT_DE),
		.TFT_PWM(TFT_PWM),
		// RAM 写
		.ram_wren(ram_wren),
		.ram_wraddress(ram_wraddress),
		.ram_input(ram_data)
	);
	
	// 按键切换逻辑
	always @(posedge Clk or negedge Rst_n)
	begin 
		if (!Rst_n)
				flush_setting <= 1;
		else
			begin
				if (flush_setting == 1)
					begin
						flush_setting <= 0;
					end
				else 
					begin
					if (system_state == 0) // 正常状态
						begin
							if (key0_p == 1) // 切换到配置状态
								system_state <= 1;
							else if (key1_p == 1) // 重置设置
								flush_setting <= 1;
							else
								option_change <= 0;
						end
					else // 配置状态
						begin 
							if(key2_p == 1) // 切换到正常状态
								begin
									system_state <= 0;
									option <= 2'b0;
								end
							else if(key0_p == 1)    // 选择配置项
								begin
									if (option + 1 > 2)
										option <= 0;
									else
										option <= option + 1;
								end
							else if(key1_p == 1) 	// 更改配置项
								begin
									option_change <= 1;
								end
							else
								option_change <= 0;
						end
				end
			end
	end
	
	
	// 接收逻辑
	always @(posedge Clk or negedge Rst_n)
	begin
		if (!Rst_n)
				receive_pos <= 12'd81;
		else
			begin
				if (rx_done == 1)
					begin
					if (receive_pos == 2239)
						receive_pos <= 12'd81;
					else if ((receive_pos + 1) % 80 == 0)
						begin 
							receive_pos <= receive_pos + 2;
						end
					else if (receive_pos % 80 == 0)
						begin 
							receive_pos <= receive_pos + 1;
						end
					else
						receive_pos <= receive_pos;
					end
				else 
					receive_pos <= receive_pos;
			end
	end
	
	// ram写逻辑
	always @(posedge Clk)
	begin
		if (rx_done == 1) // 有接收数据信号
			begin 
				ram_wren <= 1'b1;
				ram_data <= rx_data;
				ram_wraddress <= receive_pos;
			end
		else if(flush_send_setting_signal) // 有刷新发送数据信号
			begin 
				ram_wren <= 1'b1;
				ram_data <= tx_data;
				ram_wraddress <= 12'd2248;
			end
		else if(flush_bps_setting_signal) // 有波特率设置信号
			begin
				ram_wren <= 1'b1;
				ram_data <= flush_bps_setting_data;
				ram_wraddress <= flush_bps_setting_address;
			end
		else if(flush_check_setting_signal) // 有校验码设置信号
			begin
				ram_wren <= 1'b1;
				ram_data <= flush_check_setting_data;
				ram_wraddress <= flush_check_setting_address;
			end
			else   // 无信号，不可写
			ram_wren <= 1'b0;
	end
	
	
	// 发送逻辑
	always @(posedge Clk)
	begin
		if (send_en == 0)
		begin
			if (key2_p == 1 && system_state == 0)
				send_en <= 1'b1;
		end
		else
			send_en <= 1'b0;
	end
	
	// 选项配置
	always @(posedge Clk)
	begin
		if (flush_setting == 1) // 重置配置
			begin
				bps_setting <= 2'b0;  // 默认115200
				check_setting <= 1'b1; // 默认无校验
				tx_data <= 8'b0011_0000; // 默认发送字符0
			end
		else
			begin
			if(option_change == 1)
				begin
					case(option)
						0: begin // 修改发送字符配置项
								flush_send_setting <= 1;
								if (tx_data + 1 >= 8'b0111_1111)
									tx_data <= 8'd32;
								else 
									tx_data <= tx_data + 1;
							end
						1:	begin // 修改波特率配置项
								flush_bps_setting <= 1;
								if (bps_setting + 1 > 2)
									bps_setting <= 0;
								else 
									bps_setting <= bps_setting + 1;
							end
						2:begin // 修改校验码配置项 0x=>无校验 10->偶校验 11->奇校验
								flush_check_setting <= 1;
								if (bps_setting == 0)
									check_setting <= 1;
								else if(bps_setting == 3)
									check_setting <= 1'b1;
								else
									check_setting <= check_setting + 1;
						  end
					endcase
				end
			else 
				begin
					flush_send_setting <= 0;
					flush_bps_setting <= 0;
					flush_check_setting <= 0;
				end
			end
	end
	
	
	
	
	// 刷新配置
	always @(posedge Clk)
	begin
		if (flush_send_setting_signal)
			flush_send_setting_signal <= 0;
			if (flush_setting_cnt != 0)
						flush_setting_cnt <= 2;
		else if(flush_bps_setting_signal)
		begin
			case(flush_bps_setting_cnt)
			1:begin
					flush_bps_setting_cnt <= 0;
					flush_bps_setting_address <= 2259;
					begin
						case (bps_setting)
							0: flush_bps_setting_data <= 8'd49;
							1: flush_bps_setting_data <= 8'd0;
							2: flush_bps_setting_data <= 8'd0;
							default: flush_bps_setting_data <= 8'd49;
						endcase
					end
				end
			2:begin
					flush_bps_setting_cnt <= 1;
					flush_bps_setting_address <= 2260;
					begin
						case (bps_setting)
							0: flush_bps_setting_data <= 8'd49;
							1: flush_bps_setting_data <= 8'd0;
							2: flush_bps_setting_data <= 8'd0;
							default: flush_bps_setting_data <= 8'd49;
						endcase
					end
			  end
			3:begin
					flush_bps_setting_cnt <= 2;
					flush_bps_setting_address <= 2261;
					begin
						case(bps_setting)
							0: flush_bps_setting_data <= 8'd53;
							1: flush_bps_setting_data <= 8'd57;
							2: flush_bps_setting_data <= 8'd52;
							default: flush_bps_setting_data <= 8'd53;
						endcase 
					end
			  end
			4:begin
					flush_bps_setting_cnt <= 3;
					flush_bps_setting_address <= 2262;
					begin
						case (bps_setting)
							0: flush_bps_setting_data <= 8'd50;
							1: flush_bps_setting_data <= 8'd54;
							2: flush_bps_setting_data <= 8'd56;
							default: flush_bps_setting_data <= 8'd50;
						endcase
					end
			  end
			default: 
				begin
					flush_bps_setting_cnt <= 0;
					flush_bps_setting_signal <= 0;
					if (flush_setting_cnt != 0)
						flush_setting_cnt <= 1;
				end
			endcase
			end
		else if (flush_check_setting_signal)
		begin 
			case(flush_check_setting_cnt)
				1:begin
						flush_check_setting_cnt <= 0;
						flush_check_setting_address <= 2276;
						if (check_setting < 2) // 无校验
								flush_check_setting_data <= 8'd149;
						else if(check_setting == 2) // 偶校验
								flush_check_setting_data <=8'd147;
						else    // 奇校验
								flush_check_setting_data <= 8'd145;
				  end
				2:begin
						flush_check_setting_cnt <= 1;
						flush_check_setting_address <= 2275;
						if (check_setting < 2) // 无校验
								flush_check_setting_data <= 8'd148;
						else if(check_setting == 2) // 偶校验
								flush_check_setting_data <= 8'd146;
						else    // 奇校验
								flush_check_setting_data <= 8'd144;
					end
				default:begin
					flush_check_setting_cnt <= 0;
					flush_check_setting_signal <= 0;
					flush_setting_cnt <= 0;
				end
			endcase
		end
		else
		begin 
			// 刷新send_setting
			if (flush_setting == 1 || flush_send_setting == 1)
				begin
					flush_send_setting_signal <= 1; // 一回合能刷新发送的ASCII字符
				end
			// 刷新bps_setting
			else if (flush_bps_setting == 1 || flush_setting_cnt == 2)
				begin
					flush_bps_setting_signal <= 1;
					flush_bps_setting_cnt <= 4; // 由于bps_setting一回合刷新不完，所以需要在计数器中刷新
				end
			// 刷新check_setting
			else if (flush_check_setting == 1 || flush_setting_cnt == 1)
				begin
					flush_check_setting_cnt <= 2; 
					flush_check_setting_signal <= 1; // 由于check_setting一回合刷新不完，所以需要在计数器中刷新
				end
		end
	end
	
	
endmodule
